package com.yanqu.road.server.gameplayer.module.activity.goldingotfund;

import com.yanqu.road.dao.impl.activity.goldingotfund.GoldIngotFundDaoImpl;
import com.yanqu.road.entity.activity.ActivityConfig;
import com.yanqu.road.entity.activity.ActivityInfo;
import com.yanqu.road.entity.activity.goldingotfund.data.GoldIngotFundUserData;
import com.yanqu.road.entity.config.goods.MallInfo;
import com.yanqu.road.entity.enums.eGamePlayerEventType;
import com.yanqu.road.entity.enums.eLogMoneyType;
import com.yanqu.road.entity.enums.eSystemId;
import com.yanqu.road.exception.BusinessException;
import com.yanqu.road.logic.config.GameConfig;
import com.yanqu.road.logic.helper.ActivityHelper;
import com.yanqu.road.pb.activity.GoldIngotFundProto;
import com.yanqu.road.server.gameplayer.GamePlayer;
import com.yanqu.road.server.gameplayer.module.activity.ActivityModule;
import com.yanqu.road.server.gameplayer.module.base.GeneralModule;
import com.yanqu.road.server.gameplayer.module.player.CurrencyModule;
import com.yanqu.road.server.logic.activity.BaseActivityData;
import com.yanqu.road.server.logic.activity.condition.BaseActivityCondition;
import com.yanqu.road.server.manger.activity.ActivityMgr;
import com.yanqu.road.server.manger.activity.NormalActivityMgr;
import com.yanqu.road.server.manger.config.SystemOpenMgr;
import com.yanqu.road.server.protocol.ClientProtocol;
import com.yanqu.road.server.protocol.GameErrorCode;
import com.yanqu.road.utils.date.DateHelper;
import com.yanqu.road.utils.property.Property;
import com.yanqu.road.utils.property.PropertyHelper;

import java.math.BigInteger;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

public class GoldIngotFundModule extends GeneralModule {

    /**
     * 玩家数据MAP,K:活动ID,V:玩家数据
     */
    private Map<Integer, GoldIngotFundUserData> userDataMap = new ConcurrentHashMap<>();

    public GoldIngotFundModule(GamePlayer player) {
        super(player);
    }

    @Override
    public boolean loadData() {
        GoldIngotFundDaoImpl dao = new GoldIngotFundDaoImpl();
        Map<Integer, GoldIngotFundUserData> tempMap = new ConcurrentHashMap<>();
        List<GoldIngotFundUserData> activityList = dao.getGoldIngotFundUserDataList(this.getUserId());
        for (GoldIngotFundUserData userData : activityList) {
            ActivityInfo openActivityInfo = ActivityMgr.getOpenActivityInfo(userData.getActivityId());
            if (openActivityInfo != null) {
                tempMap.put(userData.getActivityId(), userData);
            }
        }
        this.userDataMap = tempMap;
        return true;
    }

    @Override
    public boolean afterLoadData() {
        return true;
    }

    @Override
    public boolean saveData() {
        GoldIngotFundDaoImpl dao = new GoldIngotFundDaoImpl();
        for (GoldIngotFundUserData userData : this.userDataMap.values()) {
            if (userData.isInsertOption()) {
                dao.add(userData);
            } else if (userData.isUpdateOption()) {
                dao.update(userData);
            }
        }
        return true;
    }

    @Override
    public void afterLogin() {
        //判断系统是否解锁
        if (SystemOpenMgr.systemOpen(player, eSystemId.GoldIngot.getValue())) {
            this.syncUserData();
        }
    }

    /**
     * 获取玩家数据
     * @param activityId
     * @return
     */
    public GoldIngotFundUserData getUserDataNewIfNull(int activityId) {
        GoldIngotFundUserData userData = userDataMap.get(activityId);
        if (userData == null) {
            userData = this.initUserData(activityId);
        }
        return userData;
    }

    /**
     * 初始化玩家数据
     * @param activityId
     */
    private synchronized GoldIngotFundUserData initUserData(int activityId) {
        GoldIngotFundUserData userData = userDataMap.get(activityId);
        if (userData == null) {
            userData = new GoldIngotFundUserData();
            userData.setActivityId(activityId);
            userData.setUserId(player.getUserId());
            userData.setInsertOption();
            userDataMap.put(activityId, userData);
        }
        return userData;
    }

    /**
     * 同步数据
     */
    public void syncUserData() {
        for (GoldIngotFundUserData userData : this.userDataMap.values()) {
            GoldIngotFundProto.GoldIngotFundUserData.Builder builder = GoldIngotFundProto.GoldIngotFundUserData.newBuilder();
            builder.setActivityId(userData.getActivityId());
            builder.addAllSignDays(userData.getSignDays());
            builder.addAllBuyMallKeyIds(userData.getBuyMallKeyIds());
            player.sendPacket(ClientProtocol.U_GOLD_INGOT_FUND_USER_DATA_SYNC, builder);
        }
    }

    /**
     * 获取补签的元宝数
     * @param activityId
     * @return
     */
    public long getBuSignCost(int activityId) {
        Map<String, ActivityConfig> activityConfigMap = NormalActivityMgr.getActivityConfigMap(activityId);
        ActivityConfig fundSignCost = activityConfigMap.get("FUND_SIGN_COST");
        if (fundSignCost != null) {
            return fundSignCost.getLongValue();
        }
        return 0;
    }

    /**
     * 签到/补签
     * @param activityId
     * @param day
     * @return
     * @throws BusinessException
     */
    public Property sign(int activityId, int day) throws BusinessException {
        //判断系统是否解锁
        if (!SystemOpenMgr.systemOpen(player, eSystemId.GoldIngot.getValue())) {
            throw BusinessException.newException(GameErrorCode.E_SYSTEM_NO_OPEN);
        }
        //获取活动
        ActivityInfo activityInfo = ActivityMgr.getOpenActivityInfo(activityId);
        if (activityInfo == null) {
            throw BusinessException.newException(GameErrorCode.E_GOLD_INGOT_FUND_ACTIVITY_NOT_FOUND);
        }
        //判断活动是否已经结束
        if (!ActivityHelper.activityInTime(activityInfo)) {
            throw BusinessException.newException(GameErrorCode.E_GOLD_INGOT_FUND_ACTIVITY_NOT_FOUND);
        }
        //拿出condition
        BaseActivityData baseActivityData = player.getModule(ActivityModule.class).getBaseActivityData(activityId);
        if (baseActivityData == null) {
            throw BusinessException.newException(GameErrorCode.E_GOLD_INGOT_FUND_CONDITION_NOT_FOUND);
        }
        //获取同一天的condition
        List<BaseActivityCondition> baseConditionList = new ArrayList<>();
        for (BaseActivityCondition baseActivityCondition : baseActivityData.getBaseActivityConditionList()) {
            if (baseActivityCondition.getConditionType() == eGamePlayerEventType.GoldIngotFund.getValue() &&
                    baseActivityCondition.getActivityConditionInfo().getParamList().get(3).intValue() == day) {
                baseConditionList.add(baseActivityCondition);
            }
        }
        if (baseConditionList.isEmpty()) {
            throw BusinessException.newException(GameErrorCode.E_GOLD_INGOT_FUND_CONDITION_NOT_FOUND);
        }
        //玩家数据
        GoldIngotFundUserData userData = this.getUserDataNewIfNull(activityId);
        //是否已经签到过
        if (userData.getSignDays().contains(day)) {
            throw BusinessException.newException(GameErrorCode.E_GOLD_INGOT_FUND_ALREADY_SIGN);
        }
        //获取活动开始导现在几天了
        int calc2DateTDOADays = DateHelper.calc2DateTDOADays(new Date(activityInfo.getBeginTime() * 1000), new Date());
        if (day <= 0 || day > calc2DateTDOADays) {
            throw BusinessException.newException(GameErrorCode.E_GOLD_INGOT_SIGN_DAY_ERROR);
        }
        if (day < calc2DateTDOADays) {
            //不是当天，需要花钱补签
            long costNum = this.getBuSignCost(activityId);
            if (costNum <= 0) {
                throw BusinessException.newException(GameErrorCode.E_GOLD_INGOT_FUND_INGOT_COST_ERROR);
            }
            Property cost = new Property(GameConfig.GAME_MONEY_INGOTS, costNum);
            boolean costFlag = player.getModule(CurrencyModule.class).removeCurrency(cost, eLogMoneyType.GoldIngotFund, eLogMoneyType.GoldIngotFundBuSignCost);
            if (!costFlag) {
                throw BusinessException.newException(GameErrorCode.E_GOLD_INGOT_FUND_INGOT_NOT_ENOUGH);
            }
        }
        //记录签到天数
        userData.addSignDay(day);
        //同步下数据
        this.syncUserData();
        //完成任务
        Property allReward = new Property();
        for (BaseActivityCondition activityCondition : baseConditionList) {
            Property reward = this.addAndGetCondition(activityCondition, day);
            allReward.addProperty(reward);
        }
        return allReward;
    }

    /**
     * 获取奖励，完成condition
     * @param activityCondition
     * @param day
     * @return
     */
    public synchronized Property addAndGetCondition(BaseActivityCondition activityCondition, int day){
        //判断奖励是否已经领取完成
        if (activityCondition.isGetReward()) {
            return null;
        }
        //判断是否是付费档
        int mallKey = activityCondition.getActivityConditionInfo().getParamList().get(0).intValue();
        if (mallKey != 0) {
            // 付费
            MallInfo mallInfo = NormalActivityMgr.getRMBActivityMallInfoByGrade(activityCondition.getActivityConditionInfo().getActivityId(), mallKey);
            if (mallInfo == null) {
                return null;
            }
            //付费档,判断是否购买了基金礼包
            boolean isBuy = this.isBuy(mallInfo);
            if (!isBuy) {
                return null;
            }
        }
        activityCondition.setValue(BigInteger.valueOf(day));
        String reward = activityCondition.getActivityConditionInfo().getRewardStr();
        Property property = PropertyHelper.parseStringToProperty(reward);
        activityCondition.setGetReward(true);
        activityCondition.removeTrigger(player);
        player.getModule(CurrencyModule.class).addCurrency(property, eLogMoneyType.GoldIngotFund, eLogMoneyType.GoldIngotFundReward);
        return property;
    }

    /**
     * 购买基金礼包
     * @param mallInfo
     */
    public void buy(MallInfo mallInfo) {
        int mallKeyId = Integer.parseInt(mallInfo.getExtendParam());
        GoldIngotFundUserData userData = this.getUserDataNewIfNull(mallInfo.getActivityId());
        userData.addBuyMallKeyId(mallKeyId);
        //把已经签到的付费档自动领一下
        Property reward = new Property();
        BaseActivityData baseActivityData = player.getModule(ActivityModule.class).getBaseActivityData(mallInfo.getActivityId());
        List<BaseActivityCondition> baseActivityConditionList = baseActivityData.getBaseConditionListByConditionType(eGamePlayerEventType.GoldIngotFund.getValue());
        for (BaseActivityCondition baseActivityCondition : baseActivityConditionList) {
            int day = baseActivityCondition.getActivityConditionInfo().getParamList().get(3).intValue();
            if (userData.getSignDays().contains(day)) {
                Property oneReward = this.addAndGetCondition(baseActivityCondition, day);
                reward.addProperty(oneReward);
            }
        }
        //同步一下补领取的档位奖励
        GoldIngotFundProto.GoldIngotFundBuyMallRewardSyncMsg.Builder builder = GoldIngotFundProto.GoldIngotFundBuyMallRewardSyncMsg.newBuilder();
        builder.setReward(PropertyHelper.parsePropertyToString(reward));
        builder.setMallReward(mallInfo.getReward());
        player.sendPacket(ClientProtocol.U_GOLD_INGOT_FUND_BUY_MALL_AUTO_RECEIVE_REWARD_SYNC, builder);
        //同步一下
        syncUserData();
    }

    /**
     * 是否购买了基金礼包
     * @param mallInfo
     * @return
     */
    public boolean isBuy(MallInfo mallInfo) {
        if (mallInfo == null) {
            return false;
        }
        int mallKeyId = Integer.parseInt(mallInfo.getExtendParam());
        GoldIngotFundUserData userData = this.getUserDataNewIfNull(mallInfo.getActivityId());
        if (userData == null) {
            return false;
        }
        return userData.getBuyMallKeyIds().contains(mallKeyId);
    }
}
